package com.hjx.leetcode;

import java.util.HashMap;
import java.util.Map;

/**
 * 273. 整数转换英文表示
 *
 * 将非负整数转换为其对应的英文表示。可以保证给定输入小于 2^31 - 1 。
 *
 * 示例 1:
 *
 * 输入: 123
 * 输出: "One Hundred Twenty Three"
 *
 * 示例 2:
 *
 * 输入: 12345
 * 输出: "Twelve Thousand Three Hundred Forty Five"
 *
 * 示例 3:
 *
 * 输入: 1234567
 * 输出: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
 *
 * 示例 4:
 *
 * 输入: 1234567891
 * 输出: "One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One"
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/integer-to-english-words
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 *
 * 执行结果： 通过
 * 显示详情
 * 执行用时 : 18 ms, 在所有 java 提交中击败了5.31%的用户
 * 内存消耗 : 36.3 MB, 在所有 java 提交中击败了80.49%的用户
 */
class LeetCode_273 {

    /**
     * 这题和12题的区别在于罗马数字，以字母个数表示数字的量，但英语不行 英语中有专门的字来表示数字的量
     * 罗马数字20 可以用 XX 英语20不可以用 Ten Ten来表示故，故思路较12题做一些转换，英语中的计数每
     * 3位一组：如： 1,234,567,890
     *
     * @param num
     * @return
     */
    public String numberToWords(int num) {
        if (num == 0){
            return "Zero";
        } else{
            return solve(num);
        }

    }

    public String solve1(int num){
        String[] reps = { "", "Thousand", "Million", "Billion", };
        String[] hundreds = { "Hundred",};
        String[] tens = {"Ninety", "Eighty", "Seventy", "Sixty", "Fifty", "Forty", "Thirty", "Twenty", "", ""};

        String[] to19 = {"Nineteen", "Eighteen", "Seventeen", "Sixteen","Fifteen", "Fourteen", "Thirteen", "Twelve", "Eleven",
                "Ten", "Nine", "Eight", "Seven", "Six", "Five", "Four", "Three", "Two", "One"
//                , "Zero"
        };

        String res = "";
        if (num == 0) {
            return "";
        }

        if (num < 20){
            return to19[to19.length - num];
        }
        if (num < 100){
            return String.format(num % 10 != 0 ? "%s %s" : "%s", tens[tens.length - 1 - (num / 10)], solve(num % 10));
        }
        if (num < 1000){
            return String.format(num % 100 != 0 ? "%s %s %s" : "%s %s", to19[to19.length - (num / 100)], hundreds[0], solve(num % 100));
        }
        for (int i = 1; i <= reps.length; i++) {
            if (num < Math.pow(1000, i)){
                return String.format(num % Math.pow(1000, i-1) != 0 ? "%s %s %s" : "%s %s",
                        solve((int) (num / Math.pow(1000, i-1))),
                        reps[i-1],
                        solve((int) (num % Math.pow(1000, i-1)))
                );
            }
        }
        return res;
    }

    public String solve(int num){
        String[] reps = { "", "Thousand", "Million", "Billion", };
        String[] hundreds = { "Hundred",};
        String[] tens = {"Ninety", "Eighty", "Seventy", "Sixty", "Fifty", "Forty", "Thirty", "Twenty", "", ""};

        String[] to19 = {"Nineteen", "Eighteen", "Seventeen", "Sixteen","Fifteen", "Fourteen", "Thirteen", "Twelve", "Eleven",
                "Ten", "Nine", "Eight", "Seven", "Six", "Five", "Four", "Three", "Two", "One"
//                , "Zero"
        };

        String res = "";
        if (num == 0) {
            return "";
        }

        if (num < 20){
            return to19[to19.length - num];
        }
        if (num < 100){
            String numText = tens[tens.length - 1 - (num / 10)];
            if(num % 10 != 0){
                return numText + " " + solve(num % 10);
            } else {
                return numText;
            }
        }
        if (num < 1000){

            String numText = to19[to19.length - (num / 100)];
            if(num % 100 != 0){
                return numText + " Hundred " + solve(num % 100);
            } else {
                return numText + " Hundred";
            }

        }
        for (int i = 1; i <= reps.length; i++) {
            if (num < Math.pow(1000, i)){
                if (num % Math.pow(1000, i-1) != 0){
                    return solve((int) (num / Math.pow(1000, i-1))) + " " + reps[i-1] + " " + solve((int) (num % Math.pow(1000, i-1)));
                } else {
                    return solve((int) (num / Math.pow(1000, i-1))) + " " + reps[i-1];
                }
            }
        }
        return res;
    }
}
